package com.interceptor;

import java.io.PrintWriter;

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.constant.AuthConstant;
import com.exception.ErrorCode.AuthErrorCode;
import com.utils.JJwtUtils;
import com.utils.RedisClient;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.http.HttpStatus;

import com.annotation.IgnoreAuth;
import com.domain.entity.TokenEntity;
import com.service.TokenService;
import com.utils.R;
import org.springframework.web.servlet.config.annotation.CorsRegistry;


@Component
public class AuthorizationInterceptor implements HandlerInterceptor {

    @Autowired
    private RedisClient redisClient;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        //支持跨域请求
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Headers", "x-requested-with,request-source,Token, Origin,imgType, Content-Type, cache-control,postman-token,Cookie, Accept,authorization");
        response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
        // 跨域时会首先发送一个OPTIONS请求，这里我们给OPTIONS请求直接返回正常状态
        if (request.getMethod().equals(RequestMethod.OPTIONS.name())) {
            response.setStatus(HttpStatus.OK.value());
            return false;
        }

        IgnoreAuth annotation = null;
        if (handler instanceof HandlerMethod) {
            //是HandlerMethod方法给
            annotation = ((HandlerMethod) handler).getMethodAnnotation(IgnoreAuth.class);
        } else {
            //如果不是HandlerMethod方法直接放行annotation赋值
            return true;
        }

        //不为null直接放行
        if (annotation != null) {
            return true;
        }

        //为空则需要验证，获取token
        String token = request.getHeader(AuthConstant.LOGIN_TOKEN_KEY);

        //判断这个token是否在redis中存在
        Boolean hasKey = redisClient.hasKey(AuthConstant.tokenPrefix + token);
        if (!hasKey) {

            //不存在代表token过期返回401前端拦截器接收到401会返回登录页面并且输出错误信息
            R notLogin = R.error(401, AuthErrorCode.USER_NOT_LOGIN.getMessage());
            String jsonStr = JSONUtil.toJsonStr(notLogin);
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/json; charset=utf-8");
            response.getWriter().write(jsonStr);
            return false;
        }

        //解析令牌
        try {
            Jwts.parser().setSigningKey(AuthConstant.SECRET).parseClaimsJws(token).getBody();
        } catch (Exception e) {

            //解析失败用户未登录
            R notLogin = R.error(401, AuthErrorCode.USER_NOT_LOGIN.getMessage());
            String jsonStr = JSONUtil.toJsonStr(notLogin);
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/json; charset=utf-8");
            response.getWriter().write(jsonStr);

            return false;

        }

        //解析成功正确放行
        return true;
    }
}
